package com.org.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blockchain.API.TimeCoinAPI;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.org.common.PageBean;
import com.org.mapper.*;
import com.org.pojo.*;
import com.org.service.*;
import com.org.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * ClassName: ServeRespondServiceImpl
 * Package: com.org.service.impl
 * Description:
 *
 * @Author Origin
 * @Create 2024/2/15 21:54
 * @Version 1.0
 */

@Service
public class ServeRespondServiceImpl extends ServiceImpl<ServeRespondMapper, ServeRespond> implements ServeRespondService {

    @Autowired
    private ServeRespondMapper serveRespondMapper;

    @Autowired
    private ServeMapper serveMapper;

    @Autowired
    private NormalUserMapper normalUserMapper;

    @Autowired
    private CommunityAdminMapper communityAdminMapper;

    @Autowired
    private ICommunityTransferCoinService communityTransferCoinService;

    @Override
    public void add(Integer serveId) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        serveRespondMapper.add(serveId, userId);
        //选择人数加1
        serveMapper.addJoinPeople(serveId);
    }

    @Override
    public void updateState(Integer serveRespondId, String state) {
        serveRespondMapper.updateState(serveRespondId, state);
    }

    //撤销响应
    @Override
    public void revoke(Integer serveRespondId) {
        ServeRespond s = serveRespondMapper.findById(serveRespondId);
        //人数减一
        serveMapper.reduceJoinPeople(s.getServeId());
//        serveRespondMapper.updateState(serveRespondId, "已撤销");
        serveRespondMapper.deleteById(serveRespondId);
    }

    @Override
    public List<ServeRespond> list(Integer id) {
        List<ServeRespond> l = serveRespondMapper.list(id);
        return l;
    }

    @Override
    public void complete(Integer id, Integer num) throws Exception {

        serveRespondMapper.updateState(id, "处理中");

        //获取服务响应信息
        ServeRespond sr = serveRespondMapper.selectById(id);
        //获取服务信息
        Serve s = serveMapper.selectById(sr.getServeId());
        Integer userType = s.getUserType();
        //获取用户信息
        NormalUser fromUser = normalUserMapper.selectById(s.getCreateId());
        NormalUser toUser = normalUserMapper.selectById(sr.getUserId());
        // 更新用户状态
        fromUser.setState("时间币交易中");
        toUser.setState("时间币交易中");
        normalUserMapper.update(fromUser);
        normalUserMapper.update(toUser);
        //获取用户密钥 01是发起人，02是接收人
        String userPK02 = toUser.getChainKey();
        String userPK01 = fromUser.getChainKey();

        //进行时间币转移
        //1.获取时间币数量
        Integer numCoins = Integer.parseInt(TimeCoinAPI.balanceOfCoin(userPK01, userPK01));
        List<BigInteger> coinIds = new ArrayList<>();
        List<String> coinHashes = new ArrayList<>();
        List<String> coinList;

        if (numCoins >= num) {
            //2.时间币转移
            //2.1 获取所有时间币id
            String coins = TimeCoinAPI.coinOfUser(userPK01, userPK01);
            String[] coinsIdAndHash = coins.split("@");
            String[] coinsInfo = coinsIdAndHash[0].split(" ");
            String[] coinsInfo2 = coinsIdAndHash[0].split(" ");

            //2.2 将查找到的前 num 个时间币转移给目标用户
            for (int i = 0; i < num; i++) {
                coinIds.add(BigInteger.valueOf(Integer.parseInt(coinsInfo[i])));
                coinHashes.add(coinsInfo2[i]);
            }
            //3. 进行时间币转移
            //3.1 取出数据库中serve.timecoins字段添加本服务受转移的时间币信息
            String timecoins = s.getTimecoins();
            // 创建一个 ObjectMapper 对象
            ObjectMapper objectMapper = new ObjectMapper();
            // 使用 ObjectMapper.readValue 方法，传入 JSON 字符串和目标类型，返回一个 List 对象
            if (timecoins != null && !timecoins.isEmpty()) {
                coinList = objectMapper.readValue(timecoins, new TypeReference<List<String>>() {
                });
            } else {
                coinList = new ArrayList<>();
            }
            //3.2合并数据库中JSON与新转移币的哈希
            coinList.addAll(coinHashes);

            // 发行
            // 4. 转移时间币
            TimeCoinAPI.transferCoin(userPK01, userPK01, userPK02, coinIds, s.getId(), s.getType());
            // 然后将转移的时间币的记录插入到时间币转移表中
            Gson gson = new Gson();
            CommunityTransferCoin log = new CommunityTransferCoin();
            log.setFromUserId(fromUser.getId());
            log.setToUserId(toUser.getId());
            log.setCoinNum(coinIds.size());
            log.setCommunityId(s.getCommunityId());
            log.setCoinIds(gson.toJson(coinHashes));
            communityTransferCoinService.save(log);

            //5. 将转移后的结果存储进数据库
            // 调用toJson方法，将list转换成json字符串
            String json = gson.toJson(coinList);
            serveMapper.updateTimecoins(json, s.getId());

        } else {
            coinList = new ArrayList<>();
            throw new Exception("时间币余额不足！");
        }
    }

    @Override
    public void delete(Integer id) {
        serveRespondMapper.deleteById(id);
    }

    @Override
    public PageBean<ServeRespond> allList(Integer pageNum, Integer pageSize, String serveId, String userId, String state) {
        //1. 创建PageBean对象
        PageBean<ServeRespond> pb = new PageBean<>();

        //2.开启分页查询
        PageHelper.startPage(pageNum, pageSize);


        QueryWrapper<ServeRespond> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("state", state);


        if (!serveId.equals("")) {
            queryWrapper.eq("serve_id", serveId);
        }

        if (!userId.equals("")) {
            queryWrapper.eq("user_id", userId);
        }


        queryWrapper.orderBy(true, false, "create_time");

        //3.调用mapper
        List<ServeRespond> as = serveRespondMapper.selectList(queryWrapper);

        //Page中提供了方法，可以获取PageHelper分页查询后 得到的总记录条数和当页数据
        Page<ServeRespond> p = (Page<ServeRespond>) as;

        //把数据填充到PageBean对象中
        pb.setTotal(p.getTotal());  //总共多少页
        pb.setItems(p); //当前页内容

        return pb;
    }

    @Override
    public void refresh() {

        QueryWrapper<ServeRespond> queryWrapper = new QueryWrapper<>();
        List<ServeRespond> listServe = serveRespondMapper.selectList(queryWrapper);
        for(ServeRespond serveRespond : listServe){
            Serve s = serveMapper.selectById(serveRespond.getServeId());
            if(s.getState().equals("进行中")){
                serveRespondMapper.updateState(serveRespond.getId(), "进行中");
            }
        }
    }
}
